package com.example.netty.tcp.handler;

import com.example.netty.tcp.DeviceClient;
import com.example.netty.tcp.message.*;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class DeviceHandler extends SimpleChannelInboundHandler<BaseMessage> {
    private static final Logger logger = LoggerFactory.getLogger(DeviceHandler.class);
    private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    private final DeviceClient client;
    private boolean loggedIn = false;
    private int loginRetryCount = 0;
    private static final int MAX_LOGIN_RETRIES = 3;

    public DeviceHandler(DeviceClient client) {
        this.client = client;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        logger.info("设备[" + client.getDeviceId() + "]连接建立，发送登录请求");
        sendLoginRequest(ctx);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, BaseMessage msg) {
        logger.debug("1. 进入 DeviceHandler.channelRead0 方法");

        if (msg instanceof LoginResponse) {
            logger.debug("2. 检测到 LoginResponse 类型消息");
            handleLoginResponse(ctx, (LoginResponse) msg);
        } else if (msg instanceof ConfigurationQueryRequest) {
            logger.debug("2. 检测到 ConfigurationQueryRequest 类型消息");
            handleConfigurationQueryRequest(ctx, (ConfigurationQueryRequest) msg);
        } else if (msg instanceof HeartbeatResponse) {
            logger.debug("2. 检测到 HeartbeatResponse 类型消息");
        } else if (msg instanceof AlarmReport) {
            logger.debug("2. 检测到 AlarmReport 类型消息");
            handleAlarmReport(ctx, (AlarmReport) msg);
        } else if (msg instanceof ControlResponse) {
            logger.debug("2. 检测到 ControlResponse  类型消息");
            handleControlResponse((ControlResponse) msg);
        } else if (msg instanceof AttributeReportResponse) {
            logger.debug("2. 检测到 AttributeReportResponse 类型消息");
            handleAttributeReportResponse((AttributeReportResponse) msg);
        } else {
            logger.warn("2. 收到未知类型消息: {}", msg.getClass().getName());
        }
    }
    private void handleControlResponse(ControlResponse response) {
        if (!client.getDeviceId().equals(response.getDevId())) {
            logger.error("响应设备ID不匹配：期望={}, 实际={}",
                    client.getDeviceId(), response.getDevId());
            return;
        }
        if (response.getResult() == 1) {
            logger.info("远程控制成功，流水号={}", response.getTxnNo());
        } else {
            logger.error("远程控制失败，流水号={}, 原因={}",
                    response.getTxnNo(), response.getErrorMessage());
        }
    }

    // 新增：处理告警上报请求的方法
    private void handleAlarmReport(ChannelHandlerContext ctx, AlarmReport report) {
        logger.info("收到告警上报: 设备ID={}, 告警数量={}",
                report.getDevId(), report.getAlarmList().size());

        // 打印告警详情（示例）
        for (AlarmReport.Alarm alarm : report.getAlarmList()) {
            logger.info("  告警ID: {}, 描述: {}, 时间: {}",
                    alarm.getId(), alarm.getAlarmDesc(), alarm.getAlarmTime());
        }

        // 返回告警上报响应
        AlarmReportResponse response = new AlarmReportResponse();
        response.setDevId(report.getDevId());
        response.setResult(1); // 1表示成功
        response.setTxnNo(report.getTxnNo()); // 使用请求中的流水号
        ctx.writeAndFlush(response);
        logger.info("已响应告警上报请求");
    }
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state() == IdleState.ALL_IDLE) {
                // 发送心跳包
                HeartbeatRequest heartbeat = new HeartbeatRequest();
                heartbeat.setDevId(client.getDeviceId());
                ctx.writeAndFlush(heartbeat);
                logger.debug("发送心跳包");
            }
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        logger.error("发生异常: {}", cause.getMessage());
        ctx.close();
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        logger.warn("设备[" + client.getDeviceId() + "]连接断开");
        loggedIn = false;
        // 可以在这里实现重连逻辑
    }

    private void sendLoginRequest(ChannelHandlerContext ctx) {
        LoginRequest login = new LoginRequest();
        login.setDevId(client.getDeviceId());
        login.setImsi("123456789012345");
        login.setBatteryStatus("2");
        login.setHardVersion("E833");
        login.setSoftVersion("1.0.0");
        login.setProtocolVersion("V2.0");
        login.setDevType(1);
        login.setTxnNo(System.currentTimeMillis());

        ctx.writeAndFlush(login);
        loginRetryCount++;
        logger.info("发送登录请求，尝试次数: {}", loginRetryCount);
    }

    private void handleLoginResponse(ChannelHandlerContext ctx, LoginResponse response) {
        if (response.getResult() == 1) {
            logger.info("设备[" + client.getDeviceId() + "]登录成功");
            loggedIn = true;
            loginRetryCount = 0;
            // 新增：登录成功后开启充电MOS（信号量01308001，值3）
            client.sendControlCommand("01308001", "3"); // 3表示开启C/D FET（参考协议）
            // 立即发送属性上报（新增逻辑）
            AttributeReport initialReport = createAttributeReport();
            ctx.writeAndFlush(initialReport);
            logger.info("立即发送初始属性上报");
            // 登录成功后，发送配置查询请求
           // sendConfigurationQueryRequest(ctx);

            // 登录成功后，启动定时属性上报任务
            scheduler.scheduleAtFixedRate(() -> {
                if (ctx.channel().isActive()) {
                    AttributeReport report = createAttributeReport();
                    ctx.writeAndFlush(report);
                    logger.info("发送属性上报消息");
                }
            }, 5, 5, TimeUnit.MINUTES); // 每5分钟上报一次
        } else {
            logger.error("设备[" + client.getDeviceId() + "]登录失败: {}", response.getReason());
            if (loginRetryCount < MAX_LOGIN_RETRIES) {
                // 登录失败，尝试重新登录
                scheduler.schedule(() -> sendLoginRequest(ctx), 5, TimeUnit.SECONDS);
            } else {
                logger.error("达到最大登录尝试次数，停止登录");
                ctx.close();
            }
        }
    }

    private void handleConfigurationQueryRequest(ChannelHandlerContext ctx, ConfigurationQueryRequest request) {
        logger.info("收到配置查询请求，设备ID: {}", request.getDevId());

        ConfigurationQueryResponse response = new ConfigurationQueryResponse();
        response.setDevId(client.getDeviceId());
        response.setResult(1); // 成功
        response.setTxnNo(request.getTxnNo());

        // 根据客户端实际数据填充响应值
        for (ConfigurationQueryRequest.Parameter param : request.getParamList()) {
            String signalId = param.getId();
            String value = getActualValueFromDevice(signalId);
            response.addResult(signalId, value);
        }

        ctx.writeAndFlush(response);
        logger.info("已响应配置查询请求，返回{}个参数", response.getResultList().size());
    }

    private void handleAttributeReportResponse(AttributeReportResponse response) {
        if (response.getResult() == 1) {
            logger.info("属性上报成功，设备ID: {}", response.getDevId());
        } else {
            logger.warn("属性上报失败，设备ID: {}", response.getDevId());
        }
    }

    private AttributeReport createAttributeReport() {
        AttributeReport report = new AttributeReport();
        report.setDevId(client.getDeviceId());
        report.setTxnNo(System.currentTimeMillis());

        // 添加多个信号量（参考之前的JSON示例）
        report.addAttribute("01113001", "85");    // SOC
        report.addAttribute("01111001", "3600");  // 总电压（36V*100）
        report.addAttribute("01115001", "1000");  // 剩余容量（10Ah*100）
        report.addAttribute("01113003", "25");    // 电池温度
        report.addAttribute("01102001", "116.3972"); // 经度
        report.addAttribute("01102002", "39.9075");  // 纬度
        report.addAttribute("01112001", "12.5");   // 单体电压（0.125V，放大100倍为12.5）
        report.addAttribute("01114001", "50");     // 充电进度

        return report;
    }

    private void sendConfigurationQueryRequest(ChannelHandlerContext ctx) {
        ConfigurationQueryRequest request = new ConfigurationQueryRequest();
        request.setDevId(client.getDeviceId());
        request.setTxnNo(System.currentTimeMillis());

        // 添加需要查询的信号量ID
        request.addParameter("01113001"); // SOC
        request.addParameter("01111001"); // 总电压
        request.addParameter("01115001"); // 剩余容量

        ctx.writeAndFlush(request);
        logger.info("发送配置查询请求");
    }

    // 从设备获取实际配置值（需根据硬件接口实现）
    private String getActualValueFromDevice(String signalId) {
        // 示例实现，实际需根据设备接口获取真实数据
        switch (signalId) {
            case "01113001": return "85"; // SOC
            case "01111001": return "3600"; // 总电压(36V*100)
            case "01115001": return "1000"; // 剩余容量(10Ah*100)
            default: return "0";
        }
    }
}
